using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Xsl;

namespace FileFolderNavigator
{
    public class FolderBackup
    {
        private static bool _firsttime = false;
        private static ProjectElement _proj;

        public static void ExecuteProjectCheckTime(ProjectElement proj)
        {
            DateTime today = DateTime.Now;
            DateTime last = DateTime.Parse(proj.Action.Last);
            DateTime next = last.AddDays(int.Parse(proj.Action.Days));

            DateTime time = DateTime.Parse(proj.Action.Time);
            if (today.TimeOfDay.CompareTo(time.TimeOfDay)>=0)
            {
                if(next.Date.CompareTo(last.Date)<=0) ExecuteProject(proj);
            }
        }

        public static void ExecuteProject(ProjectElement proj)
        {
            FolderNavigator nav;
            _proj = proj;
            _firsttime = !Directory.Exists(proj.Destination.Path + proj.Destination.Name);

            if (proj.Action.Type == "recover")
            {
                LocationElement elem = proj.Source;
                //proj.Source = proj.Destination;
                //proj.Destination = elem;
                _firsttime = true;
            }

            if (_firsttime)
            {
                nav = CreateNavigator(proj,false);
                PerformInitialBackup(nav,proj);
                if (!Directory.Exists(proj.XmlDoc.Path))
                    Directory.CreateDirectory(proj.XmlDoc.Path);
                nav.WriteTree(proj.XmlDoc.Path + proj.XmlDoc.Name);
            }
            else
            {
                nav = CreateNavigator(proj, File.Exists(proj.XmlDoc.Path + proj.XmlDoc.Name));
                nav.UpdateTree();
                if (!Directory.Exists(proj.XmlDoc.Path))
                    Directory.CreateDirectory(proj.XmlDoc.Path);
                
                nav.WriteTree(proj.XmlDoc.Path + proj.XmlDoc.Name);
            }

            if (proj.Action.Type == "recover")
            {
                LocationElement elem = proj.Source;
                //proj.Source = proj.Destination;
                //proj.Destination = elem;

                FolderNavigator recovend = new FolderNavigator(proj.Source.Path, proj.Source.Type);
                recovend.BuildTree();
                if (!Directory.Exists(proj.XmlDoc.Path))
                    Directory.CreateDirectory(proj.XmlDoc.Path);
                recovend.WriteTree(proj.XmlDoc.Path + proj.XmlDoc.Name);
            }
            proj.Action.Last = DateTime.Now.ToString();
        }

        private static FolderNavigator CreateNavigator(ProjectElement proj,bool hasxml)
        {
            FolderNavigator n = new FolderNavigator(proj.Source.Path, proj.Source.Name);
            InitializeNavigatorEvents(n);
            if (hasxml)
            {
                StringBuilder sb = new StringBuilder();

                XmlDocument doc = new XmlDocument();
                XslCompiledTransform tran = new XslCompiledTransform();
                tran.Load(new XmlTextReader(new StringReader(Resource1.stripchecked)));

                tran.Transform(new XmlTextReader(File.OpenRead(proj.XmlDoc.Path + proj.XmlDoc.Name)), new XmlTextWriter(new StringWriter(sb)));
                //n.ReadTree(proj.XmlDoc.Path + proj.XmlDoc.Name);
                n.ReadXmlString(sb.ToString());
            }
            return n;
        }

        static void InitializeNavigatorEvents(FolderNavigator nav)
        {
            nav.FileAdded += new EventHandler(nav_FileAdded);
            nav.FileChanged += new EventHandler(nav_FileChanged);
            nav.FileFound += new EventHandler(nav_FileFound);
            nav.FileRemoved += new EventHandler(nav_FileRemoved);
            nav.FolderAdded += new EventHandler(nav_FolderAdded);
            nav.FolderChanged += new EventHandler(nav_FolderChanged);
            nav.FolderFound += new EventHandler(nav_FolderFound);
            nav.FolderRemoved += new EventHandler(nav_FolderRemoved);
        }

        static void nav_FolderRemoved(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string temppath = args.Element.SubstitutePath(_proj.Destination.Path, _proj.Destination.Name);
            if (_proj.Action.Type == "sync")
            {
                if (Directory.Exists(temppath))
                {
                    Directory.Delete(temppath, true);
                }
            }
        }

        static void nav_FolderFound(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string subpath = _proj.Destination.Path;
            string subname = _proj.Destination.Name;

            string orig = args.Element.Path;
            string back = args.Element.SubstitutePath(subpath, subname);

            if (!Directory.Exists(back))
            {
                Directory.CreateDirectory(back);
            }
        }

        static void nav_FolderChanged(object sender, EventArgs e)
        {
        }

        static void nav_FolderAdded(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string subpath = _proj.Destination.Path;
            string subname = _proj.Destination.Name;

            string orig = args.Element.Path;
            string back = args.Element.SubstitutePath(subpath, subname);

            if (!Directory.Exists(back))
            {
                Directory.CreateDirectory(back);
            }
        }

        static void nav_FileRemoved(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string temppath = args.Element.SubstitutePath(_proj.Destination.Path, _proj.Destination.Name);
            if (_proj.Action.Type == "sync")
            {
                if (File.Exists(temppath))
                {
                    File.Delete(temppath);
                }
            }
        }

        static void nav_FileFound(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string subpath = _proj.Destination.Path;
            string subname = _proj.Destination.Name;

            string orig = args.Element.Path;
            string back = args.Element.SubstitutePath(subpath, subname);

            if (!File.Exists(back))
            {
                File.Copy(orig, back);
            }
        }

        static void nav_FileChanged(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string subpath = _proj.Destination.Path;
            string subname = _proj.Destination.Name;

            string orig = args.Element.Path;
            string back = args.Element.SubstitutePath(subpath, subname);

            if (File.Exists(back))
            {
                File.Delete(back);
            }
            File.Copy(orig, back);
        }

        static void nav_FileAdded(object sender, EventArgs e)
        {
            NavigatorEventArgs args = (NavigatorEventArgs)e;
            string subpath = _proj.Destination.Path;
            string subname = _proj.Destination.Name;

            string orig = args.Element.Path;
            string back = args.Element.SubstitutePath(subpath, subname);

            if (!File.Exists(back))
            {
                File.Copy(orig, back);
            }
        }

        private static void PerformInitialBackup(FolderNavigator nav,ProjectElement proj)
        {
            nav.BuildTree();
        }
    }
}
